package com.smart.service.impl;

import java.util.List;
import java.util.Arrays;
import com.smart.vo.MetaVo;
import java.util.ArrayList;
import java.util.LinkedList;
import com.smart.vo.RouterVo;
import com.smart.vo.TreeSelect;
import com.smart.entity.SysMenu;
import javax.annotation.Resource;
import java.util.stream.Collectors;
import com.smart.mapper.MenuMapper;
import com.smart.service.MenuService;
import com.smart.util.MenuTypeEnums;
import com.smart.common.util.SecurityUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import cn.hutool.core.collection.CollectionUtil;
import org.springframework.transaction.annotation.Transactional;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

/**
 * @author lgb
 * @date 2020年6月9日 下午5:45:43
 * Copyright (C) 深圳工勘科技
 * @说明: 菜单管理
 **/
@Service
public class MenuServiceImpl extends BaseServiceImpl<SysMenu,Long>
			implements MenuService{

	@Resource
	private MenuMapper menuMapper;
	
	@Override
	@Transactional(readOnly=true)
	public List<SysMenu> selectMenuList(Long userId) {
		List<SysMenu> menuList = new ArrayList<>();
        // 管理员显示所有菜单信息
        if (SecurityUtils.isAdmin(userId)) {
            menuList = list();
        } else {
            menuList = menuMapper.getPermissionList(userId);
        }
		return menuList;
	}

	/**
	 * (non-Javadoc)
	 * @see com.smart.service.MenuService#selectMenuTreeByUserId()
	 * @return 根据用户id获取菜单树
	 **/
	@Override
	@Transactional(readOnly=true)
	public List<SysMenu> selectMenuTreeByUserId(Long userId) {
		List<SysMenu> menus;
        if (SecurityUtils.isAdmin(userId)) {
            menus = list(new LambdaQueryWrapper<SysMenu>()
                    .in(SysMenu::getType,Arrays.asList(MenuTypeEnums.CATALOG.getValue(),MenuTypeEnums.MENU.getValue())));
        } else {
            menus = menuMapper.selectMenuTreeByUserId(userId);
        }
        return getChildPerms(menus, 0);
	}

	/**
     * 根据父节点的ID获取所有子节点
     * @param list     分类表
     * @param parentId 传入的父节点ID
     * @return String
     **/
    public List<SysMenu> getChildPerms(List<SysMenu> list,int parentId){
        List<SysMenu> returnList = new ArrayList<>();
        for (SysMenu t : list) {
        	// 一、根据传入的某个父节点ID,遍历该父节点的所有子节点
            if (t.getPid() == parentId) {
                recursionFn(list, t);
                returnList.add(t);
            }
        }
        return returnList;
    }
	
	/**
     * 构建前端所需要树结构
     * @param menus 菜单列表
     * @return 树结构列表
     **/
    public List<SysMenu> buildMenuTree(List<SysMenu> menus) {
        List<SysMenu> returnList = new ArrayList<>();
        for (SysMenu t : menus) {
            // 根据传入的某个父节点ID,遍历该父节点的所有子节点
            if (t.getPid() == 0) {
                recursionFn(menus, t);
                returnList.add(t);
            }
        }
        if (returnList.isEmpty()) {
            returnList = menus;
        }
        return returnList;
    }
    
    /**
     * 递归列表
     * @param list
     * @param t
     **/
    private void recursionFn(List<SysMenu> list, SysMenu t) {
        // 得到子节点列表
        List<SysMenu> childList = getChildList(list, t);
        t.setChildren(childList);
        for (SysMenu tChild : childList) {
            if (hasChild(list, tChild)) {
                // 判断是否有子节点
                for (SysMenu n : childList) {
                    recursionFn(list, n);
                }
            }
        }
    }
    
    /** 得到子节点列表 */
    private List<SysMenu> getChildList(List<SysMenu> list, SysMenu t) {
        List<SysMenu> tlist = new ArrayList<SysMenu>();
        for (SysMenu n : list) {
            if (n.getPid().longValue() == t.getId().longValue()) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /** 判断是否有子节点 */
    private boolean hasChild(List<SysMenu> list, SysMenu t) {
        return getChildList(list, t).size() > 0;
    }

	@Override
	public List<RouterVo> buildMenus(List<SysMenu> menus){
        List<RouterVo> routers = new LinkedList<RouterVo>();
        for (SysMenu menu : menus) {
            RouterVo router = new RouterVo();
            router.setName(StringUtils.capitalize(menu.getPath()));
            router.setPath(getRouterPath(menu));
            router.setComponent(StringUtils.isEmpty(menu.getUri())?"Layout":menu.getUri());
            router.setMeta(new MetaVo(menu.getName(), menu.getIcon()));
            List<SysMenu> cMenus = menu.getChildren();
            if (CollectionUtil.isNotEmpty(cMenus)&&MenuTypeEnums.CATALOG.getValue()==(menu.getType())){
                router.setAlwaysShow(true);
                router.setRedirect("noRedirect");
                router.setChildren(buildMenus(cMenus));
            }
            routers.add(router);
        }
        return routers;
    }
	 /**
     * 获取路由地址
     * @param menu 菜单信息
     * @return 路由地址
     **/
    public String getRouterPath(SysMenu menu) {
        String routerPath = menu.getPath();
        // 非外链并且是一级目录
        if (0 == menu.getPid() && "0".equals(menu.getOuterLink())) {
            routerPath = "/" + menu.getPath();
        }
        return routerPath;
    }

	@Override
	public List<SysMenu> selectMenuList(SysMenu menu, Long userId) {
		List<SysMenu> menuList = new ArrayList<>();
		// 管理员显示所有菜单信息
		if (SecurityUtils.isAdmin(userId)) {
			menuList = list();
		} else {
			menuList = menuMapper.getPermissionList(userId);
		}
		return menuList;
	}

	@Override
	public List<TreeSelect> buildMenuTreeSelect(List<SysMenu> menus) {
		List<SysMenu> menuTrees = buildMenuTree(menus);
        return menuTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
	}

	@Override
	public int create(SysMenu menu) {
		return this.baseMapper.insert(menu);
	}

	@Override
	public List<Integer> selectMenuListByRoleId(Long roleId) {
		return menuMapper.selectMenuListByRoleId(roleId);
	}
	
}